package com.qinglei.recoup.common.utils;

import com.qinglei.recoup.common.authentication.JWTUtil;
import com.qinglei.recoup.common.domain.CommonConstant;
import com.qinglei.recoup.common.function.CacheSelector;
import com.qinglei.recoup.common.service.CacheService;
import com.qinglei.recoup.system.domain.Role;
import com.qinglei.recoup.system.domain.User;
import com.qinglei.recoup.system.service.RoleService;
import com.qinglei.recoup.system.service.UserService;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;

import java.util.List;
import java.util.function.Supplier;
import java.util.stream.IntStream;

/**
 * RECOUP工具类
 */
@Slf4j
public class RecoupUtil {

    /**
     * 缓存查询模板
     *
     * @param cacheSelector    查询缓存的方法
     * @param databaseSelector 数据库查询方法
     * @return T
     */
    public static <T> T selectCacheByTemplate(CacheSelector<T> cacheSelector, Supplier<T> databaseSelector) {
        try {
            log.debug("query data from redis ······");
            // 先查 Redis缓存
            T t = cacheSelector.select();
            if (t == null) {
                // 没有记录再查询数据库
                return databaseSelector.get();
            } else {
                return t;
            }
        } catch (Exception e) {
            // 缓存查询出错，则去数据库查询
            log.error("redis error：", e);
            log.debug("query data from database ······");
            return databaseSelector.get();
        }
    }

    /**
     * 获取当前操作用户
     *
     * @return 用户信息
     */
    public static User getCurrentUser() {
        String token = (String) SecurityUtils.getSubject().getPrincipal();
        Long userId = JWTUtil.getUserId(token);
        UserService userService = SpringContextUtil.getBean(UserService.class);
        CacheService cacheService = SpringContextUtil.getBean(CacheService.class);

        return selectCacheByTemplate(() -> cacheService.getUser(userId), () -> userService.findById(userId));
    }

    /**
     * 获取当前登录用户token
     *
     * @return token
     */
    public static String getCurrentToken() {
        return (String) SecurityUtils.getSubject().getPrincipal();
    }

//    public static String getUserSubordinates(Long deptId){
//        UserService userService = SpringContextUtil.getBean(UserService.class);
//        CacheService cacheService = SpringContextUtil.getBean(CacheService.class);
//        try {
//            log.debug("query data from redis ······");
//            // 先查 Redis缓存
//           String cacheSubordinates= cacheService.getUserSubordinates(deptId);
//            if (StringUtils.isBlank(cacheSubordinates)) {
//                // 没有记录再查询数据库
//                return userService.findSubordinates(deptId);
//            } else {
//                return cacheSubordinates;
//            }
//        } catch (Exception e) {
//            // 缓存查询出错，则去数据库查询
//            log.error("redis error：", e);
//            log.debug("query data from database ······");
//            try {
//                return userService.findSubordinates(deptId);
//            } catch (Exception e1) {
//                log.error("database error：", e);
//            }
//        }
//        return null;
//    }


    /**
     * 驼峰转下划线
     *
     * @param value 待转换值
     * @return 结果
     */
    public static String camelToUnderscore(String value) {
        if (StringUtils.isBlank(value))
            return value;
        String[] arr = StringUtils.splitByCharacterTypeCamelCase(value);
        if (arr.length == 0)
            return value;
        StringBuilder result = new StringBuilder();
        IntStream.range(0, arr.length).forEach(i -> {
            if (i != arr.length - 1)
                result.append(arr[i]).append(StringPool.UNDERSCORE);
            else
                result.append(arr[i]);
        });
        return StringUtils.lowerCase(result.toString());
    }
    public static List<Role> getUserRoles(){
        String token = (String) SecurityUtils.getSubject().getPrincipal();
        Long userId = JWTUtil.getUserId(token);
        RoleService roleService = SpringContextUtil.getBean(RoleService.class);
        CacheService cacheService = SpringContextUtil.getBean(CacheService.class);
        return selectCacheByTemplate(() -> cacheService.getRoles(userId), () -> roleService.findUserRole(userId));
    }
}
